#!/bin/bash

#
# jvnc -- by Dario Berzano <dario.berzano@gmail.com>
#
# Part of the lfscripts suite -- http://lfscripts.googecode.com/
#
# Graphical launcher for the Java VNC Viewer on Mac.
#

#
# Variables
#

export VNCJAR="/opt/tightvnc-jviewer/TightVncViewer.jar"
export VNCLOG="/tmp/TightVncViewer-$USER-%s:%s:%d.log"

#
# Functions
#

# Displays a dialog with a button (label on second param) and the message
# given by the first parameter. Returns 0 if the button was pressed and 1 if
# the window has been closed with the red X.
#
# For future reference: the possible tested icons are: caution, stop, note
function WinMsg() {
  local TEXT="$1"
  local BUTTON="${2-"OK"}"
  local TITLE="${3-`basename "$0"`}"
  osascript > /dev/null 2>&1 <<OSA
    tell application "Finder"
      activate
      display dialog "$TEXT" \
        with icon note \
        with title "$TITLE" \
        buttons {"$BUTTON"} default button 1
    end tell
OSA
  return $?
}

# Asks graphically for a text string, returned on stdout. Takes parameters in
# the following order: text to display, button label, window title. Returns 0
# if the button (or Enter) was pressed, 1 if the window was closed via the red
# X.
function WinAsk() {
  local TEXT="$1"
  local DEFAULT="${2-""}"
  local BUTTON="${3-"OK"}"
  local TITLE="${4-`basename "$0"`}"
  osascript 2> /dev/null <<OSA
    tell application "Finder"
      activate
      display dialog "$TEXT" default answer "$DEFAULT" \
        buttons {"$BUTTON"} with title "$TITLE" default button 1
      text returned of result
    end tell
OSA
  return $?
}

# Separates hostname and port from the only param on the given varialbes.
# Parameters: $1 is the host:port combined string; $2/3 are the names of the
# varialbes respectively for the hostname and the port. If no port is given,
# the port variable is set to "".
function ProtoHostPort() {
  local XPROTO=`echo $1 | cut -f1 -d:`
  local XHOST=`echo $1 | cut -f2 -d:`
  local XPORT=`echo $1 | cut -f3 -d:`

  if [ "${XHOST:0:2}" == "//" ]; then
    # Complete URL with protocol
    XHOST="${XHOST:2}"
  else
    # No protocol specified
    XPORT="$XHOST"
    XHOST="$XPROTO"
    XPROTO="vnc"
  fi

  if [ "$XHOST" == "$1" ]; then
    XPORT=""
  fi

  eval "$2=\"$XPROTO\""
  eval "$3=\"$XHOST\""
  eval "$4=\"$XPORT\""
}

# Main function.
function Main() {
  local PROTO HOST PORT
  ProtoHostPort $(WinAsk "Connect to VNC server:" "vnc://localhost:5900") PROTO HOST PORT

  # Handle defaults: port 5901, encrypted tunnel
  expr "$PORT" + 0 > /dev/null 2>&1 || PORT="5901"
  [ "$PROTO" == "" ] && PROTO="ssh"

  VNCLOG=$(printf "$VNCLOG" "$PROTO" "$HOST" "$PORT")
  rm -f "$VNCLOG".0
  mv "$VNCLOG" "$VNCLOG".0 2> /dev/null

  if [ "$PROTO" == "vnc" ]; then

    # No SSH tunnel requested
    nohup java -jar "$VNCJAR" \
      HOST "$HOST" \
      PORT "$PORT" > "$VNCLOG" 2>&1 &

  elif [ "$PROTO" == "ssh" ]; then

    # SSH tunnel requested
    nohup java -jar "$VNCJAR" \
      SOCKETFACTORY com.tightvnc.vncviewer.SshTunneledSocketFactory \
      SSHHOST "$HOST" \
      HOST "localhost" \
      PORT "$PORT" > "$VNCLOG" 2>&1 &

  else

    # Unknown protocol
    WinMsg "Unknown protocol: $PROTO"

  fi

  unset PROTO HOST PORT
}

#
# Entry point
#

Main "$@"
